\documentclass{article}
\usepackage{ctex}
\usepackage{xcolor}
\usepackage{listings}
\usepackage{amsthm,amsmath,amssymb}
\usepackage{mathrsfs}
\usepackage{geometry}
\usepackage{titlesec} 
\usepackage{graphicx}
\usepackage{float}
\usepackage{subfig}
\definecolor{commentcolor}{RGB}{85,139,78}
\definecolor{stringcolor}{RGB}{206,145,108}
\definecolor{keywordcolor}{RGB}{34,34,250}
\definecolor{backcolor}{RGB}{220,220,220}
\geometry{left = 2.0cm, right = 2.0cm, top = 2.5cm, bottom = 2.5cm}
\title{CV实验1:图像滤波与傅里叶变换}
\author{姓名:隋佳成 \and 班级:人工智能91 \and 学号:2193712551 \and 密码：SJC\_CVPR01}
\date{\today}

\usepackage{accsupp}	
\newcommand{\emptyaccsupp}[1]{\BeginAccSupp{ActualText={}}#1\EndAccSupp{}}

\usepackage{listings}
\lstset{						        %高亮代码设置
	language=python, 					%Python语法高亮
	linewidth=0.9\linewidth,      		%列表list宽度
	%basicstyle=\ttfamily,				%tt无法显示空格
	commentstyle=\color{commentcolor},	%注释颜色
	keywordstyle=\color{keywordcolor},	%关键词颜色
	stringstyle=\color{stringcolor},	%字符串颜色
	%showspaces=true,					%显示空格
	numbers=left,						%行数显示在左侧
	numberstyle=\tiny\emptyaccsupp,		%行数数字格式
	numbersep=5pt,						%数字间隔
	frame=single,						%加框
	framerule=0pt,						%不划线
	escapeinside=@@,					%逃逸标志
	emptylines=1,						%
	xleftmargin=3em,					%list左边距
	backgroundcolor=\color{white},	    %列表背景色
	tabsize=4,							%制表符长度为4个字符
	gobble=4							%忽略每行代码前4个字符
	}

\begin{document}
    \newpagestyle{main}{            
        \sethead{}{计算机视觉实验报告}{}     %设置页眉
        \setfoot{}{\thepage}{}                     %设置页脚，可以在页脚添加 \thepage  显示页数
        \headrule                                  % 添加页眉的下划线                                      %添加页脚的下划线
    }
    \pagestyle{main}                               %使用该style
    \maketitle
    \section*{\kaishu{一 \quad 实验目的}}
        本次实验主要是高斯滤波和傅里叶变换的实验。
        分为如下几个部分：
        \begin{enumerate}
            \item [-] 2D高斯模板的设计(给定标准差生成滤波核)，进而对图像高斯滤波，并在高斯滤波中以不同边界处理方法处理图像的实验
            \item [-] 利用两个相同标准差的一维高斯核生成2维高斯核的实验
            \item [-] 利用一维高斯滤波核对图像进行滤波，不同标准差的高斯核对图像进行滤波
            \item [-] 设计图像锐化滤波器核
            \item [-] 图像的双边滤波
            \item [-] 图像的傅里叶变换，显示幅度谱和相位谱，利用高斯滤波器进行图像的频率域滤波
        \end{enumerate}
    \section*{\kaishu{二 \quad 实验环境}}
    Windows10操作系统, VSCode
    \section*{\kaishu{三 \quad 实验方法}}
    \subsection*{3.1 \quad 原理}
    \begin{enumerate}
        \item 高斯核以及卷积：高斯核可以起到模糊图像的作用，就是利用周围的像素值，以一种加权的方式计算该像素点新的像素值，这样，原本像素值变化很大的地方变化变小，并且可以将区域变得平滑，
            起到模糊的作用。通过将原图和模糊后的图像相减，我们可以得到原图像中的一些细节信息，将这些细节信息再加回到原图像上，可以加强原图像的细节信息。
        \item 双边滤波：双边滤波不仅考虑图像像素点之间的空间距离，还考虑图像像素点之间的像素值差距，通过这种策略，可以较好的保留图像的边缘信息，同时可以起到高斯核中的平滑作用，可谓一举两得。
        \item 图像的傅里叶变换：傅里叶变换可以将图像拆分成多个基加权相加的形式，当然这个权值也可能是复数，但是这样来说就提取到了图像的高频和低频信息，更利于后面的图像处理。经过傅里叶变换得到图像的
            基、频谱图和相位图，就可以得到图像的高频低频信息，频谱图可以很好的反应图像中的高频和低频信息分布，而相位图可以很好的保存图像的纹理特征，这就为我们通过已有图片合成新图片提供了方法。
            比如我们可以对两张不同的图片分别做傅里叶变换，得到了两张图片的幅度图和相位图后可以交叉使用逆变换，这样我们就能将一张图片的纹理信息和另一张图片的频率信息结合在一起，生成新图片。
        \item 在处理图像滤波时，有FULL，SAME和VALID三种策略，FULL是只要滤波器核和原图像有交点，就对其进行滤波，SAME策略只有当滤波器核中心与图像有重合才进行滤波，而VALID只有滤波核完全在图像中，
            才进行滤波。同时在这三种策略应用时，关于边界补全也有四种不同的策略，有边界均补全零(zero)，也有边界直接复制(copy)，也有图像平移来补全边界(wrap)，还有映射的方法补全边界(reflect)，不同的边界处理
            方法对图像滤波有着不同的影响，在我们的实验中，我们对常用的SAME、VALID和zero、copy和wrap来进行实验。
    \end{enumerate}
    \subsection*{3.2 \quad 方法}
        首先，说明一下。我们利用图片\ref{fig:rgbraw}进行所有操作，由于图片\ref{fig:rgbraw}为RGB图像，我们首先把他转化为灰度图像，如\ref{fig:lraw}所示。
        \begin{figure}[h!]
            \centering
            \subfloat[RGB raw Image]{%
            \includegraphics[width=2.6cm]{../1.jpg}%
            \label{fig:rgbraw}%
            }\qquad
            \subfloat[L raw Image]{%
            \includegraphics[width=2.6cm]{../GK/rawImage.jpg}%
            \label{fig:lraw}%
            }
            \caption{图a为RGB的图片，我们不用rgb的，用图b灰度图像}
            \label{fig:RawImages}
        \end{figure}
        下面介绍一下代码中的各个方法。
        \begin{enumerate}
            \item [-] def gause1DKernel(kernel\_size, sigma) 将会返回一个numpy数组，数组的形状为[1, kernel\_size]，数组是一个归一化后的一维高斯滤波器，其中标准差为sigma
            \item [-] def gauseKernel(kernel\_size, sigma) 将会返回一个numpy数组，数组的形状为[kernel\_size, kernel\_size]，数组是一个归一化后的二维高斯滤波器，其中标准差为sigma
            \item [-] class Conv2D是一个二维卷积类，在初始化时给定滤波器数量(filters)，卷积核大小(kernel\_size)，卷积核标准差起始值(sigma)，还有边界处理方法(padding, boundary)，其中padding默认为valid.
                      在初始化后(conv = Conv2D)，利用call成员方法即可传入需要进行变换的图片。
                    \begin{lstlisting}
        conv = Conv2D(1, kernel_size, sigma, "zero", "SAME")
        output = conv(image))
                    \end{lstlisting}
            \item [-] class Conv1D是一个一维卷积类，在初始化时给定滤波器数量(filters)，卷积核大小(kernel\_size)，卷积核标准差起始值(sigma)，还有边界处理方法(padding)，其中padding默认为valid.
                      在初始化后(c = Conv1D)，利用call成员方法即可传入需要进行变换的图片(c(image))。
            \item [-] def single2DKernelFiltering(kernel\_size, sigma, boundary, padding)将会利用一个二维高斯核对图像进行滤波,并将滤波后的图片储存在GK文件夹下。
            \item [-] def single1DKernelFiltering(kernel\_size, sigma, padding)将会利用一个一维高斯核对图像进行滤波，并将滤波后的图片储存在GK文件夹下。
            \item [-] def detailExtract()将会对图像进行细节提取，具体方法就是原图减去一个经过模糊的图像，并将提取后的细节储存在GK文件夹下。
            \item [-] def sharpen()将会对图像进行锐化，具体方法是原图加上提取到的细节信息，并将锐化后的图片储存在GK文件夹下。
            \item [-] def subOfTwoKernel(size1, sigma1, size2, sigma2)将会利用两个高斯核的差对图像进行卷积处理，其中四个参数分别是两个高斯核的大小和标准差,并将滤波后的图片储存在GK文件夹下。
            \item [-] def generate2DWith1Ds(kernel\_size, sigma)将会利用两个相同标准差的一维高斯核生成一个二维高斯核，并将其返回。
            \item [-] class FourierTransform()是一个傅里叶变换类。初始化时不需要给定任何参数，在调用时直接传入需要进行傅里叶变换的图片image即可，image可以是PIL.Image类，也可是numpy数组。在FT文件夹下，保存有傅里叶变换得到的各种结果。
            \begin{lstlisting}
        FT = FourierTransform()
        B, F, Fabs, e = FT(image)
            \end{lstlisting} 如上所示，B为基的字典，F为系数矩阵，Fabs为系数的幅度谱，e为系数的相位谱
            \item [-] def reconstructImage(imageL\_arr, F, B)用于使用傅里叶变换得到的基和系数来重构图片。
        \end{enumerate}
        
    % \lstset{numbers=left, 
    % numberstyle=\tiny, 
    % keywordstyle=\color{blue!70},commentstyle=\color{red!50!green!50!blue!50}, 
    % frame=shadowbox, 
    % rulesepcolor=\color{red!20!green!20!blue!20} 
    % } 
    \section*{\kaishu{四 \quad 实验结果}}

    如图\ref{fig:FTB}给出了傅里叶变换下一些基的图片。

    \begin{figure}[h!]
        \centering
        \subfloat[FourierTransform Basis Example1]{%
        \includegraphics[width=2.6cm]{../FT/B_-47,-41.jpg}%
        \label{fig:FTB1}%
        }\qquad
        \subfloat[FourierTransform Basis Example2]{%
        \includegraphics[width=2.6cm]{../FT/B_-47,-42.jpg}%
        \label{fig:FTB2}%
        }\qquad
        \subfloat[FourierTransform Basis Example3]{%
        \includegraphics[width=2.6cm]{../FT/B_-47,-43.jpg}%
        \label{fig:FTB3}%
        }\qquad
        \subfloat[FourierTransform Basis Example4]{%
        \includegraphics[width=2.6cm]{../FT/B_-47,-44.jpg}%
        \label{fig:FTB4}%
        }\qquad
        \subfloat[FourierTransform Basis Example5]{%
        \includegraphics[width=2.6cm]{../FT/B_-47,-45.jpg}%
        \label{fig:FTB5}%
        }
        \caption{FourierTransform Basis}
        \label{fig:FTB}
    \end{figure}

    如图\ref{fig:FabsAndE}给出了对应的幅度谱和相位谱的实数部分。可以看到幅度谱\ref{fig:Fabs}只有中间一点是比较大的值，向外基本都是很小的黑色像素，这说明，
    这张图片的高频信息很少，大多是低频信息。
    为验证我的傅里叶变换是否正确，用傅里叶变换得到的基和系数试着重构原图片。事实证明，傅里叶变换正确，如图\ref{fig:ReconImage}所示。
    \begin{figure}[h!]
        \centering
        \subfloat[F abs Image]{%
        \includegraphics[width=2.6cm]{../FT/FabsImage.jpg}%
        \label{fig:Fabs}%
        }\qquad
        \subfloat[e Image]{%
        \includegraphics[width=2.6cm]{../FT/eRealImage.jpg}%
        \label{fig:eReal}%
        }\qquad
        \subfloat[重构图片]{%
        \includegraphics[width=2.6cm]{../FT/reconImage.jpg}%
        \label{fig:ReconImage}%
        }
        \caption{图a为幅度谱，图b为相位谱的实数部分}
        \label{fig:FabsAndE}
    \end{figure}
    
    如图\ref{fig:GK}给出了部分高斯滤波的各个结果。对比图\ref{fig:compare}来看，在二维的高斯滤波中，
    图片的横向和纵向都有一定程度的模糊，但是一维的高斯滤波中，图片的纵向模糊不明显，横向模糊较为明显，我想这也是预想到的，因为二维高斯滤波可以看作两个一维高斯滤波的结合。
    从图\ref{fig:GKsharpen}可以看出比较明显的锐化效果。需要注意的是，由于步长是1，所以可能无法明显的看出来same和valid时，图片大小的变化。
    
    也可以看到在双边滤波实验中，相比直接的滤波较好的保留了图片边缘的信息。

    
    
    \begin{figure}[htbp]
        \centering
        \subfloat[Bilateral filtered Image(sigma = 1, padding = SAME, zero)]{%
        \includegraphics[width=2.6cm]{../GK/BilateralFiltered.jpg}%
        \label{fig:GKfiltered2D3V}%
        }\qquad
        \subfloat[1D filtered Image(sigma = 1)]{%
        \includegraphics[width=2.6cm]{../GK/1DfilteredImage1SAME.jpg}%
        \label{fig:GKfiltered1D1S}%
        }\qquad
        \subfloat[1D filtered Image(sigma = 3)]{%
        \includegraphics[width=2.6cm]{../GK/1DfilteredImage3SAME.jpg}%
        \label{fig:GKfiltered1D3S}%
        }\qquad
        \subfloat[detailExtracted Image]{%
        \includegraphics[width=2.6cm]{../GK/detailExtracted.jpg}%
        \label{fig:GKdetail}%
        }\qquad
        \subfloat[raw Image]{%
        \includegraphics[width=2.6cm]{../GK/rawImage.jpg}%
        \label{fig:GKraw}%
        }\qquad
        \subfloat[sharpen Image]{%
        \includegraphics[width=2.6cm]{../GK/shapenedImage.jpg}%
        \label{fig:GKsharpen}%
        }\qquad
        \caption{高斯滤波结果}
        \label{fig:GK}
    \end{figure}
    图\ref{fig:compare}显示了不同边界方法和不同sigma状态下图片滤波后的结果。可以发现的是，在sigma=1和sigma=100时，
    图片滤波后似乎差别不大，但实际上是有差别的，将两个相同策略不同sigma的图片相同位置相减后，发现像素值的差别有些在1以内，有些可以达到6,7，说明
    有差别，但是差别不大，我觉得最主要的原因就是，这个图片本身高频的部分不多，这一点从细节提取图\ref{fig:GKdetail}的图片以及幅度谱\ref{fig:Fabs}中也可以看出来，所以sigma变化
    对高频信息通过的差别不大。
    \begin{figure}[h!]
        \centering
        \subfloat[2D filtered Image(sigma = 1, padding = SAME, zero)]{%
        \includegraphics[width=2.6cm]{../GK/2DfilteredImage1zeroSAME.jpg}%
        \label{fig:GKfiltered2D1S}%
        }\qquad
        \subfloat[2D filtered Image(sigma = 1, padding = SAME, copy)]{%
        \includegraphics[width=2.6cm]{../GK/2DfilteredImage1copySAME.jpg}%
        \label{fig:GKfiltered2D3S}%
        }\qquad
        \subfloat[2D filtered Image(sigma = 1, padding = valid, zero)]{%
        \includegraphics[width=2.6cm]{../GK/2DfilteredImage1zerovalid.jpg}%
        \label{fig:GKfiltered2D1V}%
        }\qquad
        \subfloat[2D filtered Image(sigma = 1, padding = valid, wrap)]{%
        \includegraphics[width=2.6cm]{../GK/2DfilteredImage1wrapvalid.jpg}%
        \label{fig:GKfiltered2D3V}%
        } \\
        \subfloat[2D filtered Image(sigma = 100, padding = SAME, zero)]{%
        \includegraphics[width=2.6cm]{../GK/2DfilteredImage100zeroSAME.jpg}%
        \label{fig:GKfiltered2D1S}%
        }\qquad
        \subfloat[2D filtered Image(sigma = 100, padding = SAME, copy)]{%
        \includegraphics[width=2.6cm]{../GK/2DfilteredImage100copySAME.jpg}%
        \label{fig:GKfiltered2D3S}%
        }\qquad
        \subfloat[2D filtered Image(sigma = 100, padding = valid, zero)]{%
        \includegraphics[width=2.6cm]{../GK/2DfilteredImage100zerovalid.jpg}%
        \label{fig:GKfiltered2D1V}%
        }\qquad
        \subfloat[2D filtered Image(sigma = 100, padding = valid, wrap)]{%
        \includegraphics[width=2.6cm]{../GK/2DfilteredImage100wrapvalid.jpg}%
        \label{fig:GKfiltered2D3V}%
        }\qquad
        \caption{不同边界方法下不同sigma对比}
        \label{fig:compare}
    \end{figure}
    
   
    \section*{\kaishu{五 \quad 理论部分}}
    \subsection*{5.1 \quad 2D卷积与互相关的定义、性质推导或证明及其复杂度分析}
    卷积公式是$g(i,j) = \underset{k,l}{\sum}f(i-k, j-l)h(k, l)$，互相关公式是$g(i,j) = \underset{k,l}{\sum}f(i+k, j+l)h(k, l)$，可以看出来的是，卷积核旋转180度即可得到相应的相关核。
    2D卷积和互相关都有一下性质：
    \begin{enumerate}
        \item 线性移不变性:$ h\circ (f_0 + f_1) = h\circ f_0 + h\circ f_1 $
        这个性质很好证明，由于卷积和相关都是矩阵的对应位置相乘，或者是旋转一百八十度之后的对应位置相乘，也可以看作对应位置相乘的一种变形，所以每一个位置都可以写成上面的形式，两张图片的同一位置相加后，再与相应位置的卷积核或者相关核相乘，扩展开
        写就可以得到上面的式子。$ h[k,l]\circ (f_0[i,j] + f_1[i,j]) = h[k,l]\circ f_0[i,j] + h\circ f_1[i,j] $注意，这个式子中的所有量均为标量了，我们就好理解了。
        \item 位移不变性:$ g(i,j) = f(i+m,j+n) \Leftrightarrow (h\circ g)(i,j) = (h \circ f)(i+m,j+n)$
            这个证明利用卷积的定义即可。g与h的卷积$G(i,j) = \underset{k,l}{\sum}g(i-k, j-l)h(k, l) = \underset{k,l}{\sum}f(i+m-k, j+n-l)h(k, l) = F(i+m,j+n)$得证。
    \end{enumerate}
    
    时间复杂度：假设卷积核尺寸为$k_1\times k_2$，图像尺寸为$M\times N$，那么时间复杂度为$\bigcirc (k_1 \times k_2\times M \times N)$

    \subsection*{5.2 \quad 2D高斯可分离性推导}

    对于一个二维高斯核$g[i,j] = ke^{-\frac{i^2+j^2}{2\sigma^2}}$,令f是一个图像。
    \begin{equation*}
        \begin{aligned}
            f * g &= \sum_k \sum_l g[k,l]f[i-k,j-l]\\
            &=\sum_k \sum_l ke^{-\frac{k^2+l^2}{2\sigma^2}} f[i-k,j-l]\\
            &=k\sum_k e^{-\frac{k^2}{2\sigma^2}} \left\{ \sum_l e^{-\frac{l^2}{2\sigma^2}} f[i-k,j-l] \right\} \\
            &=f * g_c * g_r
        \end{aligned}
    \end{equation*}
            
    如式子中，图像依次和两个一维高斯核进行卷积与图像直接和二维高斯核卷积等价

    \subsection*{5.3 \quad 2D空间卷积定理和2D频率卷积定理推导}
    \begin{enumerate}
        \item 2D频率卷积定理：如果有$h = f * g$，则有$H = FG$其中H,F,G为h,f,g的傅里叶变换.
        下面证明这一结论。
        \begin{equation*}
            \begin{aligned}
                H(w) &=  \int_{-\infty}^{+\infty} f * g(t)e^{-iwt} \,dt\\  
                    &= \int_{-\infty}^{+\infty}\int_{-\infty}^{+\infty} f(\tau )g(t-\tau) d\tau e^{-iwt} \,dt\\
                    &=\int_{-\infty}^{+\infty} f(\tau )\int_{-\infty}^{+\infty}g(t-\tau)  e^{-iwt} \,dtd\tau \\
                    &=\int_{-\infty}^{+\infty} f(\tau )G(w)e^{-iw\tau}d\tau\\
                    &=G(w)F(w)
            \end{aligned}
        \end{equation*}

        证毕。

        \item 2D空间卷积定理：如果有$H = F * G$，则有$h = fg$。有了2D频率卷积定理证明的式子，这个就非常好证明了，只需要对
        $H = F * G$做傅里叶逆变换，通过像频率卷积定理类似的证明方式，就可以得到结果。
        \begin{equation*}
            \begin{aligned}
                h(t) &=  \int_{-\infty}^{+\infty} F(w) * G(w)e^{iwt} \,dw\\  
                    &= \int_{-\infty}^{+\infty}\int_{-\infty}^{+\infty} F(\tau )G(w-\tau) d\tau e^{iwt} \,dw\\
                    &=\int_{-\infty}^{+\infty} F(\tau )\int_{-\infty}^{+\infty}G(w-\tau)  e^{iwt} \,dwd\tau \\
                    &=\int_{-\infty}^{+\infty} F(\tau )g(t)e^{it\tau}d\tau\\
                    &=g(t)f(t)
            \end{aligned}
        \end{equation*}
    \end{enumerate}
    
\end{document}